#ifndef TRACKING_H
#define TRACKING_H

#include <iostream>
#include "Frame.h"
#include "Map.h"
#include "KeyFrame.h"
#include "MapPoint.h"

#include <stdint.h>
#include "LocalMapping.h"
#include "Viewer.h"

class Map;
class LocalMapping;
class Viewer;


class Tracking
{
public:
	 Tracking(Map* pMap, MapDrawer* pMapDrawer);
	 ~Tracking();

	void UpdateLastFrame();

	int SearchByProjection(Frame &CurrentFrame, const Frame &LastFrame, const float th, const bool bMono);
	
	int SearchByBruteForce(KeyFrame *pKF, Frame &F, std::vector<MapPoint*> &vpMapPointMatches);

	int PoseOptimization(Frame *pFrame);

	void StereoInitialization();

	bool TrackReferenceKeyFrame();

	bool TrackLocalMap();

	int SearchByProjection(Frame &F, const std::vector<MapPoint*> &vpMapPoints, const float th);

	void CreateNewKeyFrame();

	void UpdateLocalKeyFrames();

	void UpdateLocalPoints();

	void SearchLocalPoints();

	float RadiusByViewingCos(const float &viewCos);

	void track(const cv::Mat &imRectLeft, const cv::Mat &imRectRight, const double &timestamp, cv::Mat &K, cv::Mat &distCoef, const float &bf, float thDepth = 3.85f);

	bool NeedNewKeyFrame();

	void SetLocalMapper(LocalMapping* pLocalMapper);

	void SetViewer(Viewer* pViewer);

private:
	Frame m_CurrentFrame;
	Frame m_LastFrame;

	//Local Map
	KeyFrame* m_ReferenceKF;
	KeyFrame* m_LastKeyFrame;
	std::vector<KeyFrame*> m_vectorLocalKeyFrames;
	std::vector<MapPoint*> m_vectorLocalMapPoints;
	unsigned int m_LastKeyFrameId;
	bool m_init = false;

	//Current matches in frame
	int m_MatchesInliers;

	float m_ThDepth;

	//Other Thread Pointers
    LocalMapping* m_LocalMapper;

	//New KeyFrame rules (according to fps)
    int m_MinFrames;
    int m_MaxFrames;

	Map* m_Map;

	Viewer* m_Viewer;
	MapDrawer* m_MapDrawer;
};
#endif  //TRACKING_H
